/*******************************************************************************
 ** Name: main.cpp                                                            **
 ** Description: A basic ATK calculator.                                      **
 **                                                                           **
 ** Open Source Initiative (OSI) Approved License                             **
 **                                                                           **
 ** The contents of this file are subject to the terms of the                 **
 ** Common Development and Distribution License, Version 1.0 only             **
 ** (the "License").  You may not use this file except in compliance          **
 ** with the License.                                                         **
 **                                                                           **
 ** You can find a copy of the license in the LICENSE file within             **
 ** this distribution or at $WIKI/display/ODS/License-software.              **
 ** Software distributed under the License is distributed on an "AS IS"       **
 ** basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.           **
 ** See the License for the specific language governing permissions           **
 ** and limitations under the License.                                        **
 **                                                                           **
 ** When distributing Covered Code, include this CDDL header in each          **
 ** file and include the License file at $GAME_DIR/LICENSE.                   **
 ** If applicable, add the following below this header, with the indicated    **
 ** fields enclosed by brackets "[]" replaced with your own identifying       **
 ** information: Portions Copyright [yyyy] [name of copyright owner]          **
 **                                                                           **
 ** Copyright (c) 2009-2012 Open Design Strategies, LLC                       **
 ** All rights reserved.                                                      **
 ******************************************************************************/
// $HeadURL$
// Modified $Date$ by $Author$
// $Id$

#include <iostream>
#include <math.h>

#define VERSION "1.0"

void	InvalidRange(void);
double	CalcPHIT(void);

int los, weather, visibility;
int firearms, size, feats, char_move, tgt_move, acc, recoil, range, gear, stance, position;
int avd;

int main()
{
	char ch;

	std::cout << "ATK Calculator version " << VERSION << std::endl;

	do
	{
		los:
		std::cout << "Line of Sight [0,1]: ";
		std::cin >> los;
		if (los < 0 || los > 1)
		{
			InvalidRange();
			goto los;
		}
		
		vis:
		std::cout << "Visibility [0,1]: ";
		std::cin >> visibility;
		if (visibility < 0 || visibility > 1)
		{
			InvalidRange();
			goto vis;
		}

		fireams:
		std::cout << "Firearms skill bonus [0:12]: ";
		std::cin >> firearms;
		if (firearms < 0 || firearms > 12)
		{
			InvalidRange();
			goto fireams;
		}
		
		talents:
		std::cout << "Talent bonus [0:5]: ";
		std::cin >> feats;
		if (feats < 0 || feats > 5)
		{
			InvalidRange();
			goto talents;
		}

		sz:
		std::cout << "Size bonus (0 is normal) [-6:6]: ";
		std::cin >> size;
		if (size < -6 || size > 6)
		{
			InvalidRange();
			goto sz;
		}

		cmv:
		std::cout << "Character movement speed [0:50]: ";
		std::cin >> char_move;
		if (char_move < 0 || char_move > 50)
		{
			InvalidRange();
			goto cmv;
		}

		tmv:
		std::cout << "Target movement speed [0:50]: ";
		std::cin >> tgt_move;
		if (tgt_move < 0 || tgt_move > 50)
		{
			InvalidRange();
			goto tmv;
		}

		wacc:
		std::cout << "Weapon accuracy (%) [0:100]: ";
		std::cin >> acc;
		if (acc < 0 || acc > 100)
		{
			InvalidRange();
			goto wacc;
		}

		rcl:
		std::cout << "Weapon recoil [0:25]: ";
		std::cin >> recoil;
		if (recoil < 0 || recoil > 25)
		{
			InvalidRange();
			goto rcl;
		}

		rinc:
		std::cout << "Range increment [1:4]: ";
		std::cin >> range;
		if (range < 1 || range > 4)
		{
			InvalidRange();
			goto rinc;
		}

		gb:
		std::cout << "Gear bonus [0:4]: ";
		std::cin >> gear;
		if (gear < 0 || gear > 4)
		{
			InvalidRange();
			goto gb;
		}

		stnc:
		std::cout << "Stance bonus [0:3]: ";
		std::cin >> stance;
		if (stance < 0 || stance > 3)
		{
			InvalidRange();
			goto stnc;
		}

		pos:
		std::cout << "Position bonus (Stand: 0, Kneel: 3, Prone: 6): ";
		std::cin >> position;
		if (position != 0 && position != 3 && position != 6)
		{
			InvalidRange();
			goto pos;
		}

		avoid:
		std::cout << "What is target's AVD (%): ";
		std::cin >> avd;
		if (avd < 0 || avd > 100)
		{
			InvalidRange();
			goto avoid;
		}

		std::cout << "Target's chance to hit is " << CalcPHIT() << "%" << std::endl;

		std::cout << "Calculate another (y/n)? ";
		std::cin >> ch;

	} while (ch == 'y');

	return 0;
}

double CalcPHIT()
{
	if (visibility == 0 || los == 0)
		return 0;

	double dsz;
	if (size == 0) dsz = 1;
	else dsz = size * 0.01;
	double dcmv;
	if (char_move == 0) dcmv = 1;
	else dcmv = 1/(log(char_move)/2);
	double dtmv;
	if (tgt_move == 0) dtmv = 1;
	else dtmv = 1/(log(tgt_move)/2);
	double dacc = acc * 0.01;
	double drec;
	if (recoil == 0) drec = 1;
	else drec = recoil * 0.01;
	
	double drng;
	switch(range)
	{
	case 1:
		drng = dacc;	
		break;
	case 2:
		drng = dacc/1.5;
		break;
	case 3:
		drng = dacc/2.5;
		break;
	case 4:
		drng = dacc/5;
		break;
	}

	double dfs;
	if (firearms == 12)
		dfs = 11.5/12;
	else
		dfs = firearms/12;

	double dtal;
	if (feats == 5)
		dtal = 4.5/5;
	else
		dtal = feats/5;

	double dgear = gear * 0.025;

	double dpos = position * 0.01;
	double dstnc = stance * 0.01;
	
	double ret = dsz * dcmv * dtmv * dacc * drec * drng * (dfs + dtal + dgear + dpos + dstnc);
	std::cout << dsz << " * " << dcmv << " * " << dtmv << " * " << dacc << " * " << drec << " * " << drng << " * ";
	std::cout << "(" << dfs << " + " << dtal << " + " << dgear << " + " << dpos << " + " << dstnc << ") = " << ret;
	std::cout << std::endl;
	return (ret * 100);
}

void InvalidRange(void)
{
	std::cerr << "Invalid range." << std::endl;
}
